查看原文
其他

R语言编程秘籍:一文掌握循环结构,让你的代码更智能!

游南 游北向难 2024-04-02

R语言编程秘籍:一文掌握循环结构,让你的代码更智能!

介绍

在R语言中,循环结构和应用函数提供了多种灵活的方法来处理数据和执行任务。在该文中,详细介绍了各种循环结构和函数的用法。

首先是传统的循环结构,如for循环、while循环和repeat循环,它们分别适用于不同的迭代需求,比如遍历固定次数的操作或在满足特定条件时重复执行。此外,foreach循环提供了一种简洁的并行迭代方式,适用于列表、向量或数据框的元素。

除了循环结构,apply()函数族,包括apply()、lapply()、sapply()、tapply()和vapply(),它们提供了一种在数据结构上应用函数的简便方式,减少了显式的循环。

由purrr包提供的map函数系列,包括map()、map2()和pmap(),它们提供了一种更灵活、更功能丰富的方式来应用函数到列表或向量的元素上。

通过了解和掌握这些循环结构和函数,读者可以根据实际情况选择最合适的方法来处理数据或执行任务,从而提高R语言编程的效率和灵活性。

示意图

本文包含内容:

  • for循环

    • for循环 usage

    • for循环 example

  • while循环

    • while循环 usage

    • while循环 example

  • repeat循环

    • repeat循环 usage

    • repeat循环 example

  • foreach循环

    • foreach循环 usage

    • foreach循环 example

  • apply()函数

    • apply()函数 usage

    • apply()函数 example

  • tapply()函数

    • tapply()函数 usage

    • tapply()函数 example

  • lapply()函数

    • lapply()函数 usage

    • lapply()函数 example

  • sapply()函数

    • sapply()函数 usage

    • sapply()函数 example

  • vapply()函数

    • vapply()函数 usage

    • vapply()函数 example

  • map()函数

    • map()函数 usage

    • map()函数 example

  • map2()函数

    • map2()函数 usage

    • map2()函数 example

  • pmap()函数

    • pmap()函数 usage

    • pmap()函数 example

循环结构

for循环

for循环 usage

## Target: for循环 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

for (variable in sequence) {
  # 循环体
}
# variable是循环变量,sequence是需要迭代的序列,循环体中的代码会在每次迭代中执行

for循环 example

## Target: for循环 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 使用for循环计算向量中元素的平方
vec <- c(12345)
for (i in 1:length(vec)) {
  vec[i] <- vec[i] ^ 2
}
print(vec)

# 输出结果:[1]  1 4 9 16 25

while循环

while循环 usage

## Target: while循环 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

while (condition) {
  # 循环体
}
# condition是一个逻辑表达式,只要条件为真,就会一直执行循环体中的代码

while循环 example

## Target: while循环 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 使用while循环计算斐波那契数列
a <- 0
b <- 1
n <- 10
i <- 1
fib <- c()
while (i <= n) {
  fib[i] <- a
  next_num <- a + b
  a <- b
  b <- next_num
  i <- i + 1
}
print(fib)

# 输出结果: [1]  0  1 1 2 3 5 8 13 21 34

repeat循环

repeat循环 usage

## Target: repeat循环 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

repeat {
  # 循环体
  if (condition) {
    break
  }
}
# condition是一个逻辑表达式,当条件为真时,执行break语句跳出循环

repeat循环 example

## Target: repeat循环 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 使用repeat循环计算正整数的立方和,直到立方和超过100
sum_cubes <- 0
i <- 1
repeat {
  cube <- i^3
  sum_cubes <- sum_cubes + cube
  if (sum_cubes > 100) {
    break
  }
  i <- i + 1
}
print(sum_cubes)

# 输出结果:[1] 225

foreach循环

foreach循环 usage

## Target: foreach循环 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

foreach (variable = values, .combine = combine_function) %do% {
  # 循环体
}
# variable是循环变量,values是需要迭代的值,.combine是一个函数

foreach循环 example

## Target: foreach循环 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 使用foreach循环计算列表中每个元素的平方,并将结果合并为一个新的向量
library(foreach)
list_data <- list(12345)
square_list <- foreach (num = list_data) %do% {
  num^2
}
print(square_list)

# 输出结果:[[1]]
#         [1] 1

#         [[2]]
#         [1] 4

#         [[3]]
#         [1] 9

#         [[4]]
#         [1] 16

#         [[5]]
#         [1] 25

apply函数族

apply()函数

对矩阵或数组的行或列应用函数

apply()函数 usage

## Target: apply()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 对矩阵或数组的行或列应用函数
apply(X, MARGIN, FUN, ..., simplify = TRUE)
# X是需要进行操作的矩阵或数组
# MARGIN指定对那个维度进行操作,取值1表示行,2表示列
# FUN是要应用的函数,可以是内置函数,也可以是自定义的函数
# simplify=TRUE时(默认),apply函数会尝试简化结果为更小的数据结构,例如向量或矩阵.若为FALSE,apply函数会保存结果的原始形式,即使每次应用函数的结果是标量.

apply()函数 example

## Target: apply()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 对矩阵的行求和
mat <- matrix(1:9, nrow = 3)

apply(mat, 1, sum) # 对每一行求和
# 输出结果:[1] 12 15 18

apply(mat, 2, mean) # 对每一列求平均值
# 输出结果:[1] 2 5 8

tapply()函数

主要用于对数据进行分组并对各组应用指定的函数

tapply()函数 usage

## Target: tapply()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 主要用于对数据进行分组并对各组应用指定的函数
tapply(X, INDEX, FUN = NULL..., default = NA, simplify = TRUE)
# X要进行操作的数据向量或数据框
# INDEX一个用来分组的因子(factor)或者一个由因子组成的列表
# FUN要应用于每个分组的函数.可以是内置函数,也可以是自定义函数
# ...其他传递给FUN的参数
# default当某一组为空时的默认返回值
# simplify逻辑值,指定当结果是简单矩阵或数组时是否简化输出

tapply()函数 example

## Target: tapply()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 创建数据
grades <- c(8590889278899183)
classes <- c("A""B""A""B""A""B""A""A")
# 使用tapply计算每个班级的平均成绩
class_avg <- tapply(grades, classes, mean)
print(class_avg)

# 输出结果:       A        B
#         85.00000 90.33333 

lapply()函数

对列表中的每个元素应用函数,并返回一个列表

lapply()函数 usage

## Target: lapply()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 对列表中的每个元素应用函数,并返回一个列表
lapply(X, FUN)
# X表示输入的列表或向量
# FUN表示要应用的函数,可以是内置函数,也可以是自定义函数

lapply()函数 example

## Target: lapply()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 创建一个列表
my_list <- list(a = 1:5, b = 6:10, c = 11:15)
# 对每个元素应用mean函数
lapply(my_list, mean)

# 输出结果:$a
#         [1] 3

#         $b
#         [1] 8

#         $c
#         [1] 13

sapply()函数

对列表中的每个元素应用函数

sapply()函数 usage

## Target: sapply()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 对列表中的每个元素应用函数,并尝试简化结果
sapply(X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
# X表示要输入的列表或向量
# FUN表示要应用的函数,可以是内置函数,也可以是自定义函数
# ...其他传递给FUN的参数
# simplify,逻辑值,用于控制是否尝试简化结果,默认为TRUE
# USE.NAMES,逻辑值,用于控制是否使用输入的列表或向量的名称作为结果的名称,默认为TRUE

sapply()函数 example

## Target: sapply()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 创建一个列表
my_list <- list(a = 1:5, b = 6:10, c = 11:15)
# 对每个元素应用mean函数,并简化结果
sapply(my_list, mean)

# 输出结果:a b c
#           3  8 13 

vapply()函数

对向量应用函数,并指定返回值的类型

vapply()函数 usage

## Target: vapply()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 对向量应用函数,并指定返回值的类型
vapply(X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE)
# X表示一个列表或向量
# FUN表示要应用的函数,可以是内置函数,也可以是自定义函数
# FUN.VALUE给定FUN函数的返回值类型,通常是一个样本的空数据结构,用于确定返回值的类型和结构
# ...其他传递给FUN的参数
# USE.NAMES,逻辑值,用于控制是否使用输入的列表或向量的名称作为结果的名称,默认为TRUE

vapply()函数 example

## Target: vapply()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# 创建一个向量
my_vector <- c(3691215)
# 计算向量中每个元素的平方根,返回值为numeric类型
vapply(my_vector, function(x) sqrt(x), numeric(1))

# 输出结果:[1] 1.732051 2.449490 3.000000 3.464102 3.872983

purrr泛函式循环迭代

map()函数

map() 函数用于对单个列表或向量进行迭代,对每个元素应用同一个函数,并将结果存储在列表中。

map()函数 usage

## Target: map()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

library(purrr)

map(.x, .f, ..., .progress = FALSE)
# .x表示要处理的列表,向量等对象
# .f表示要应用的函数
# ...用于传递额外的参数给.f
# .progress,逻辑值,表示是否显示进度条,默认为FALSE

map_lgl(.x, .f, ..., .progress = FALSE)
# 类似于map,返回的是逻辑型向量

map_int(.x, .f, ..., .progress = FALSE)
# 类似于map,返回的是整数型向量

map_dbl(.x, .f, ..., .progress = FALSE)
# 类似于map,返回的是双精度型(double)向量

map_chr(.x, .f, ..., .progress = FALSE)
# 类似于map,返回的是字符型向量

map_vec(.x, .f, ..., .ptype = NULL, .progress = FALSE)
# 类似于map,返回的向量类型由.ptype参数指定

walk(.x, .f, ..., .progress = FALSE)
# 类似于map,不返回任何值,仅用于执行副作用(例如修改对象)

map()函数 example

## Target: map()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# R包加载
library(purrr)
# 创建一个向量
vec <- c(12345)

# map()
# 使用map函数对向量中的每个元素求平方
result <- map(vec, ~ .x^2)
print(result)

# 输出结果:[[1]]
#         [1] 1

#         [[2]]
#         [1] 4

#         [[3]]
#         [1] 9

#         [[4]]
#         [1] 16

#         [[5]]
#         [1] 25


# map_lgl()
# 判断向量中的每个元素是否大于2
result <- map_lgl(vec, ~ .x > 2)
print(result)

# 输出结果:[1] FALSE FALSE TRUE TRUE TRUE


# map_int()
# 对向量中的每个元素取整
result <- map_int(vec, ~ as.integer(.x))
print(result)

# 输出结果:[1] 1 2 3 4 5


# map_dbl()
# 对向量中的每个元素取对数
result <- map_dbl(vec, ~ log(.x))
print(result)

# 输出结果:[1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379


# map_chr()
# 对向量中的每个元素转换为字符型
result <- map_chr(vec, ~ as.character(.x))
print(result)

# 输出结果:[1] "1" "2" "3" "4" "5"


# map_vec()
# 将向量中的每个元素转换为逻辑型
result <- map_vec(vec, ~ as.logical(.x))
print(result)

# 输出结果:[1] TRUE TRUE TRUE TRUE TRUE


# walk()
# 对列表中的每个元素打印出来
walk(vec, ~ print(.x))

# 输出结果:[1] 1
#         [1] 2
#         [1] 3
#         [1] 4
#         [1] 5

map2()函数

map2() 函数用于对两个列表或向量进行迭代,对应位置的元素一一匹配,应用相同的函数,并将结果存储在列表中。

map2()函数 usage

## Target: map2()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

library(purrr)

map2(.x, .y, .f, ..., .progress = FALSE)
# .x第一个输入对象,如向量,列表等
# .y第二个输入对象,与.x相同长度的向量,列表等
# .f要应用的函数
# ...用于传递额外参数给.f
# .progress,逻辑值,表示是否显示进度条,默认为FALSE

map2_lgl(.x, .y, .f, ..., .progress = FALSE)
# 类似于map2(),返回逻辑型向量

map2_int(.x, .y, .f, ..., .progress = FALSE)
# 类似于map2(),返回整数型向量

map2_dbl(.x, .y, .f, ..., .progress = FALSE)
# 类似于map2(),返回双精度型向量

map2_chr(.x, .y, .f, ..., .progress = FALSE)
# 类似于map2(),返回字符型向量

map2_vec(.x, .y, .f, ..., .ptype = NULL, .progress = FALSE)
# 类似于map2(),返回的向量类型由.ptype参数指定
# .ptype用于指定返回的向量类型,默认为null

walk2(.x, .y, .f, ..., .progress = FALSE)
# 类似于map2(),但不返回任何值,仅用于执行副作用(例如修改对象)

map2()函数 example

## Target: map2()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

library(purrr)

# map2()
# 示例:将两个向量中对应元素相加
result <- map2(1:34:6, ~ .x + .y)
print(result)

# 输出结果:[[1]]
#         [1] 5

#         [[2]]
#         [1] 7

#         [[3]]
#         [1] 9


# map2_lgl()
# 示例:将两个逻辑型向量中对应元素进行逻辑或操作
result_logical <- map2_lgl(c(TRUEFALSETRUE), c(FALSETRUETRUE), ~ .x | .y)
print(result_logical)

# 输出结果:[1] TRUE TRUE TRUE


# map2_int()
# 示例:将两个整数型向量中对应元素相乘
result_int <- map2_int(1:34:6, ~ .x * .y)
print(result_int)

# 输出结果:[1]  4 10 18


# map2_dbl()
# 示例:将两个双精度型向量中对应元素取对数
result_dbl <- map2_dbl(c(101001000), c(234), ~ log(.x, base = .y))
print(result_dbl)

# 输出结果:[1] 3.321928 4.191807 4.982892


# map2_chr()
# 示例:将两个字符型向量中对应元素进行字符串拼接
result_chr <- map2_chr(c("Hello""Good"), c("World""Morning"), ~ paste(.x, .y, sep = ", "))
print(result_chr)

# 输出结果:[1] "Hello, World"  "Good, Morning"


# map2_vec()
# 示例:将两个向量中对应元素相加,并返回向量结果
result_vec <- map2_vec(1:34:6, ~ .x + .y)
print(result_vec)

# 输出结果:[1] 5 7 9


# walk2()
# 示例:对两个向量中对应元素进行打印操作
walk2(letters[1:3], LETTERS[4:6], ~ cat(.x, .y, sep = "-"))

# 输出结果:a-Db-Ec-F

pmap()函数

pmap() 函数用于对多个列表或向量进行迭代,每个列表中的元素一一匹配,应用相同的函数,并将结果存储在列表中。

pmap()函数 usage

## Target: pmap()函数 usage
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

library(purrr)

pmap(.l, .f, ..., .progress = FALSE)
# .l包含输入参数的列表
# .f要应用的函数
# ...用于传递额外参数个.f
# .progress逻辑值,表示是否显示进度条,默认为FALSE

pmap_lgl(.l, .f, ..., .progress = FALSE)
# 类似于pmap(),返回逻辑型向量

pmap_int(.l, .f, ..., .progress = FALSE)
# 类似于pmap(),返回整数型向量

pmap_dbl(.l, .f, ..., .progress = FALSE)
# 类似于pmap(),返回双精度型向量

pmap_chr(.l, .f, ..., .progress = FALSE)
# 类似于pmap(),返回字符型向量

pmap()函数 example

## Target: pmap()函数 example
## Time: 2024/03/30
## Author: xiaohe
## Notes: zhenzhen

# R包加载
library(purrr)
# 定义一个列表,包含多个向量
list_of_vectors <- list(
  x = c(123),
  y = c(456),
  z = c(789)
)

# pmap()
# 对列表中的向量相加
result <- pmap(list_of_vectors, sum)
print(result)

# 输出结果:[[1]]
#         [1] 12

#         [[2]]
#         [1] 15

#         [[3]]
#         [1] 18


# pmap_lgl() 
# 对列表中的逻辑型向量进行逻辑与操作
logical_list <- list(
  a = c(TRUETRUEFALSE),
  b = c(TRUEFALSEFALSE),
  c = c(FALSEFALSEFALSE)
)

result_logical <- pmap_lgl(logical_list, all)
print(result_logical)

# 输出结果:[1] FALSE FALSE FALSE


# pmap_int() 
# 对列表中的整数型向量进行乘法操作
int_list <- list(
  a = c(123),
  b = c(456),
  c = c(789)
)

result_int <- pmap_int(int_list, function(a, b, c) a * b * c)
print(result_int)

# 输出结果:[1]  28 80 162


# pmap_dbl() 
# 列表中的双精度型向量进行平方根操作
dbl_list <- list(
  a = c(1.02.03.0),
  b = c(4.05.06.0),
  c = c(7.08.09.0)
)

result_dbl <- pmap_dbl(dbl_list, function(a, b, c) sqrt(a + b + c))
print(result_dbl)

# 输出结果:[1] 3.464102 3.872983 4.242641


# pmap_chr()
# 对列表中的字符型向量进行拼接操作
chr_list <- list(
  a = c("hello""world"),
  b = c("how""are"),
  c = c("you""doing")
)

result_chr <- pmap_chr(chr_list, paste, collapse = " ")
print(result_chr)

# 输出结果:[1] "hello how you"   "world are doing"


备注

大家有兴趣可加群,欢迎交流学习,共同进步!

若群链接失效,可在本公众号内的对话框回复关键词【R语言学习交流群

直接扫码进群
欢迎扫码添加本人

若您觉得本文有帮助,帮忙点击点赞在看是对我最大的鼓励和支持!



继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存